/**
 * Created by jiangxiaowei on 2017/1/6.
 */


let fse = require('fs-extra');
let fs =require('fs');
let path  =require('path');
let http = require('http');
var loadUpdateService =require('../service/load-update-service');
let {ossClient} = loadUpdateService;
import {generateTplJSCss} from '@qianmi/x-site-common/util/template-compile-util';
import {loadNpmPackage} from './npm-load-util'
let ossPrefix = '/x-site/${env}/public/barRepo/';

/**
 * 根据模板配置文件,生成模板加载JS文件...
 * 包含组件集合, 插件
 */
export async function generateTplInfo ({templateConfig,envCode}){
    let dependenciesBar  = await _analyseTemplateDependentBar({templateConfig,envCode});
    templateConfig.dependenciesBar = dependenciesBar;
    return templateConfig;
}

/**
 *
 * 模板模板配置文件 生成模板注入JS
 * 生成模板的逻辑应该与tpl-中的一样... 这里要共用才行
 *
 * @param workBenchPath
 * @param templateConfig
 */
export async function generateTemplateConfigContent ({projectName,templateConfig,envCode,distDir}) {

    //先验证加载的包...
    console.log('模板模板配置文件 生成模板注入JS',projectName,envCode,distDir);

    if(templateConfig.dependenciesBar){
        let toLoadTplNpm  = [];
        for(let i =0,ilen=templateConfig.dependenciesBar.length ; i<ilen; i++) {
            let _npmName = templateConfig.dependenciesBar[i].split('/')[0];

            if(toLoadTplNpm.indexOf(_npmName) ===-1){
                toLoadTplNpm.push(_npmName);
            }
        }

        //验证跟环境上的是否一致...
        for(let i  =0,ilen =toLoadTplNpm.length;i<ilen;i++) {
            await _checkAndLoadEnvNpm({envCode,tplDirName:toLoadTplNpm[i]})
        }
    }

   let result = await generateTplJSCss({
       templateConfig,
       loadWidgetFile:({widgetFilePath})=>{
           return _loadWidgetJSFile(widgetFilePath,distDir);
      }
   });

    return result;
}



async function _checkAndLoadEnvNpm({envCode,tplDirName}){
    //http://qianmi-web.oss-cn-hangzhou.aliyuncs.com
    let enVJson = await loadJson(`/x-site/${envCode}/public/barRepo/${tplDirName}/barIndex.json`);
    // TODO 如果 版本号是OK的, 那么就不搞了.

    let {npmPackageDir}  =  await loadNpmPackage({
        distDir:path.join(__dirname,'../temp'),
        version:enVJson['version'] as string,
        name:"@qianmi/"+tplDirName
    });
    return npmPackageDir;
}

async function loadJson(src){
    let response = await ossClient.getObjectAbsolute(src);
    return JSON.parse( response.content.toString());
}



/**
 * 加载编译后的JS的代码. 前提已经保证在temp 中加载过依赖的模板项目了
 * @param widgetNs
 * @param widgetDefaultProps
 * @return {{js: *, css: string}}
 * @private
 */
async function _loadWidgetJSFile(widgetFilePath, distDir) :Promise<string> {

    let widgetWorkBench = getNsWorkBenchName(widgetFilePath);
    let widgetPath = path.join(distDir, '@qianmi/' + widgetWorkBench + '/dist/barRepo', widgetFilePath);
    console.log('读取每个组件的js -p.js .css',distDir,widgetPath,'========================================================');
    let content  = await loadFile(widgetPath);
    return content  as string;
}

async function loadFile(filePath){
    return new Promise((resolve,reject)=>{
        fs.readFile(filePath, (err, data) => {
            err?reject(err):resolve(data.toString());
        });
    });
}

/**
 * 分析出模板所依赖的所有组件
 * @param templateCnnfig
 */
async function _analyseTemplateDependentBar({templateConfig,envCode}){
    let result =[];
    for (let i=0; i<templateConfig.children.length; i++) {
        result.push(templateConfig.children[i].widgetNameSpace);
        let space = await searchNameSpaceFromFile(templateConfig.children[i].widgetNameSpace,envCode);
        result = result.concat(space);
    }

    if (templateConfig.acceptBars) {
        for (let i=0; i<templateConfig.acceptBars.length; i++) {
            result.push(templateConfig.acceptBars[i]);
            let space = await searchNameSpaceFromFile(templateConfig.acceptBars[i],envCode);
            result = result.concat(space);
        }
    }

    if (templateConfig.pluginBars) {
        for (let i=0; i<templateConfig.pluginBars.length; i++) {
            result.push(templateConfig.pluginBars[i]);
            let space = await searchNameSpaceFromFile(templateConfig.pluginBars[i],envCode);
            result = result.concat(space);
        }
    }

    if (templateConfig.adapterBars) {
        for (let i=0; i<templateConfig.adapterBars.length; i++) {
            result.push(templateConfig.adapterBars[i]);
            let space = await searchNameSpaceFromFile(templateConfig.adapterBars[i],envCode);
            result = result.concat(space);
        }
    }

    return result;
}

/**
 * 根据指定组件 找到其直接或间接依赖的子组件
 * @param widgetNameSpace 组件命名空间
 * @param topDir 顶部目录
 **/
async function searchNameSpaceFromFile(widgetNameSpace,envCode){
    let widgetWorkBench = widgetNameSpace.split('/');
    let barIndex;
    try {
        let _path = path.join(__dirname, '../temp/dist/' + widgetWorkBench[0] + '/barIndex.json');
        let isExist = fse.existsSync(_path);
        if (isExist) {
            barIndex = fse.readJsonSync(_path);
        } else {
            barIndex = await ossClient.getObjectAbsolute(ossPrefix.replace('${env}',envCode) + widgetWorkBench[0] + '/barIndex.json');
            barIndex = JSON.parse(barIndex.content.toString());
            fse.outputJsonSync(_path, barIndex);
        }

        return barIndex[widgetNameSpace].dependenciesBar || [];
    } catch (err) {
        return [];
    }
}

function getNsWorkBenchName(widgetNs){
    let _all = widgetNs.split('/');
    return _all[0];
}

function getWorkBenchName(projectName){
    let _all  = projectName.split('/');
    return _all[1];
}
